#pragma once
#include "CQNetBase.h"

namespace CQLIB {
	namespace CQNET
	{
		class LIBCQNET_API CQAcceptor_TCP : public std::enable_shared_from_this<CQAcceptor_TCP>
		{
		public:
			CQAcceptor_TCP(const std::string ip = DEF_IP, int port = 0, void* cb = nullptr, void* ptr = nullptr,
				io_service& io_ = CQIoServiceManager::obj()->get_io_service());
			~CQAcceptor_TCP();

			bool write_to_all(const std::string& msg);

			bool write_to_one(int key, const std::string& msg);
			void close_all() const;
			void close_one(int key) const;
			void stop_io_accept() const { io_service_.stop(); }
		private:
			void accept();
			void accept_handler(const boost_error_code& ec, CQSock_Ptr sock);
			int get_key() { return key_++; }
			void close(CQSock_Ptr csp) const;
			bool do_read(CQSock_Ptr csp);
			bool do_write(CQSock_Ptr csp, const std::string& msg);
			bool on_read(const boost_error_code& ec, std::size_t length, CQSock_Ptr csp);
			bool on_write(const boost_error_code& ec, CQSock_Ptr csp) const;

			void cb_timer_safety_certificate(bool ec, CQSock_Ptr& csp);
		private:
			io_service& io_service_;
			endpoint_type listen_end_;
			acceptor_type acceptor_;
			int key_ = CQKEYBEGIN::value;
			callbacks_s* cb_;
			void* ptr_;
			session_ptr session_;
			CQTimer_List<CQSock_Ptr> ctl;
		};

		using Server_Ptr = std::shared_ptr<CQAcceptor_TCP>;
		using TimerCallBack = std::function<void(bool, CQSock_Ptr&)>;
	}
}